package com.scs.application.modules.device.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.flow.FlowContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.UtilNum;
import com.scs.application.modules.device.entity.DeviceCirculate;
import com.scs.application.modules.device.entity.DeviceCirculateItem;
import com.scs.application.modules.device.entity.DeviceCirculateSettings;
import com.scs.application.modules.device.enums.DeviceBusMap;
import com.scs.application.modules.device.mapper.DeviceCirculateMapper;
import com.scs.application.modules.device.service.DeviceCirculateItemService;
import com.scs.application.modules.device.service.DeviceCirculateService;
import com.scs.application.modules.device.service.DeviceCirculateSettingsService;
import com.scs.application.modules.device.service.DeviceLedgerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *  设备租赁、归还 服务实现类
 */
@Service
public class DeviceCirculateServiceImpl extends BaseServiceImpl<DeviceCirculateMapper, DeviceCirculate> implements DeviceCirculateService {
    @Lazy
    @Autowired
    private DeviceCirculateItemService deviceCirculateItemService;

    @Lazy
    @Autowired
    private DeviceLedgerService deviceLedgerService;

    @Lazy
    @Autowired
    private DeviceCirculateSettingsService deviceCirculateSettingsService;

    @Override
    public boolean saveOrUpdate(DeviceCirculate entity) {
        if (entity.isNewRecord()) {
            entity.setBusKey(serialRuleAdapter.getSerialRuleService().generateCode(DeviceBusMap.getSerialKey(entity.getBusType())));
        }
        return super.saveOrUpdate(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeCascadeByIds(Collection<? extends Serializable> idList) {
        List<String> childIdList = deviceCirculateItemService.list(Wrappers.<DeviceCirculateItem>query().in("circulate_id", idList)).stream().map(DeviceCirculateItem::getId).collect(Collectors.toList());
        if (ObjectUtil.length(childIdList) > 0) {
            deviceCirculateItemService.removeCascadeByIds(childIdList);
        }

        return super.removeCascadeByIds(idList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void afterHandleFlowChange(FlowContext flowContext, DeviceCirculate newEntity) {
        List<DeviceCirculateItem> childList = deviceCirculateItemService.list(Wrappers.<DeviceCirculateItem>query().eq("circulate_id", newEntity.getId()));
        if (!flowContext.isEndNode()) {
            return;
        }
        BusinessException.throwErrorIf(ObjectUtil.length(childList) == 0, "业务明细为空，无法审核通过");
        _afterWo(newEntity,childList);
        _afterReturn(newEntity,childList);
        // 处理台账信息
        deviceLedgerService.transferByCirculate(childList, newEntity,flowContext.getButton());
        deviceLedgerService.unlockBatch(childList.stream().map(DeviceCirculateItem::getLedgerId).collect(Collectors.toList()));
    }

    /***
     * @param
     * @Description:  借出审核
     */
    private void _afterWo(DeviceCirculate work, List<DeviceCirculateItem> childList) {
        if (!work.getBusType().equals(DeviceBusMap.DEVICE_CIRCULATE_OUT)) {
            return;
        }

        childList.stream().filter(item -> item.getBorrowTime() == null).findFirst().ifPresent(find -> {
            BusinessException.throwError("设备[%s]借用时间为空,请检查",find.getDeviceName());
        });

        childList.stream().filter(item -> item.getExpectTime() == null).findFirst().ifPresent(find -> {
            BusinessException.throwError("设备[%s]预计归还时间为空,请检查",find.getDeviceName());
        });

        // 更新共享设备的属性
        List<String> ledgerIdList = childList.stream().map(DeviceCirculateItem::getLedgerId).collect(Collectors.toList());
        Map<String,DeviceCirculateItem> mapByLedgerId =  childList.stream().collect(Collectors.toMap(DeviceCirculateItem::getLedgerId, item -> item));
        List<DeviceCirculateSettings> settingsList = deviceCirculateSettingsService.list(Wrappers.<DeviceCirculateSettings>query().in("ledger_id",ledgerIdList));
        for (DeviceCirculateSettings set : settingsList) {
            deviceCirculateSettingsService.update(Wrappers.<DeviceCirculateSettings>update()
                    .set("flag_circulate", GlobalConsts.YES_STR)
                    .set("borrow_dept_id", work.getBorrowDeptId())
                    .set("borrow_dept_name", work.getBorrowDeptName())
                    .set("borrow_time", mapByLedgerId.get(set.getLedgerId()).getBorrowTime())
                    .set("expect_time", mapByLedgerId.get(set.getLedgerId()).getExpectTime())
                    .eq("ledger_id",set.getLedgerId())
            );
        }
    }

    /***
     * @param
     * @Description:  还入审核
     */
    private void _afterReturn(DeviceCirculate work, List<DeviceCirculateItem> childList) {
        if (!work.getBusType().equals(DeviceBusMap.DEVICE_CIRCULATE_RETURN)) {
            return;
        }

        childList.stream().filter(item -> item.getReturnTime() == null).findFirst().ifPresent(find -> {
            BusinessException.throwError("设备[%s]实际归还时间为空,请检查",find.getDeviceName());
        });

        // 更新共享设备的属性
        List<String> ledgerIdList = childList.stream().map(DeviceCirculateItem::getLedgerId).collect(Collectors.toList());
        List<String> woItemIdList = childList.stream().map(DeviceCirculateItem::getWoItemId).collect(Collectors.toList());
        List<DeviceCirculateSettings> settingsList = deviceCirculateSettingsService.list(Wrappers.<DeviceCirculateSettings>query().in("ledger_id",ledgerIdList));
        Map<String,DeviceCirculateItem> mapByLedgerId =  childList.stream().collect(Collectors.toMap(DeviceCirculateItem::getLedgerId, item -> item));
        BusinessException.throwErrorIf(ObjectUtil.length(ledgerIdList) != ObjectUtil.length(mapByLedgerId.keySet()), "共享设备缺失,请检查");


        Double accuQuantity = 0d;
        Double accuAmount = 0d;
        for (DeviceCirculateSettings set : settingsList) {
            set.setFlagCirculate(GlobalConsts.NO);
            if (set.getAccuAmount() == null) {
                set.setAccuAmount(0d);
            }
            if (set.getAccuQuantity() == null) {
                set.setAccuQuantity(0d);
            }
            deviceCirculateSettingsService.update(
                    Wrappers.<DeviceCirculateSettings>update()
                            .setSql("borrow_dept_id=null,borrow_dept_name=null,borrow_time = null,expect_time = null")
                            .set("flag_circulate",GlobalConsts.NO_STR)
                            .set("accu_amount",UtilNum.sum(set.getAccuAmount() ,mapByLedgerId.get(set.getLedgerId()).getCostAmount()) )
                            .set("accu_quantity",set.getAccuQuantity() + 1 )
                            .eq("id",set.getId())
            );
        }
        if(!woItemIdList.isEmpty()) {
            deviceCirculateItemService.update(
                    Wrappers.<DeviceCirculateItem>update()
                            .set("flag_return",GlobalConsts.YES_STR)
                            .set("return_key",work.getBusKey())
                            .in("id",woItemIdList)
            );
        }

    }
}